//
// Created by sherlock on 2021/2/28.
//

#ifndef TCPSERVER_H
#define TCPSERVER_H

#include "header.h"

class TcpServerPrivateData;

class TcpSocket;

class TcpServer
{
public:
    enum HostAddress
    {
        LocalHost = 0,  //The IPv4 localhost address. 127.0.0.1
        LocalHostIPv6,  //The IPv6 localhost address. ::1
        Broadcast,      //The IPv4 broadcast address. 255.255.255.255
        AnyIPv4,        //The IPv4 any-address. 0.0.0.0. A socket bound with this address will listen only on IPv4 interaces.
        AnyIPv6,        //The IPv6 any-address. ::. A socket bound with this address will listen only on IPv6 interaces.
        Any             //The dual stack any-address. A socket bound with this address will listen on both IPv4 and IPv6 interfaces.
    };

public:
    TcpServer();

    explicit TcpServer(uv_loop_t *loop);

    virtual ~TcpServer();

    void setMaxConnect(unsigned int max);

    bool listen(HostAddress hostAddress, unsigned int port);

    /**
     * @brief:  获取最近一次错误描述
     * @author: sherlock
     */
    std::string getLastErrorMessage() const;

    /**
     * @brief:  根据错误码获取错误描述
     * @author: sherlock
     */
    static std::string getErrorMessage(int errorCode);

public:
    virtual void newConnect(TcpSocket *tcpSocket);

    typedef void (*OnNewConnect)(TcpSocket *tcpSocket, void *userData);

    void setNewConnectCB(OnNewConnect onNewConnect, void *userData);

private:
    void initializeData();

private:
    static void newConnectionCB(uv_stream_t *server, int status);

private:
    std::unique_ptr<TcpServerPrivateData> data;
};


#endif //LIBUVTEST_TCPSERVER_H
